package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.base.CommonResponse;
import com.gap.basic.exception.BizException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.entity.vo.ConsumerLocationGroupItemVO;
import com.mingqijia.gassafety.db.entity.vo.ConsumerLocationItemVO;
import com.mingqijia.gassafety.db.entity.vo.ConsumerLocationStatItemVO;
import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.shared.constant.BusinessNoticeParam;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.ServicePkgEnum;
import com.mingqijia.gassafety.shared.dto.UserFuncCodePermissionDTO;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.LocationUtil;
import com.mingqijia.gassafety.webserver.dto.AdInfoDTO;
import com.mingqijia.gassafety.webserver.feign.ConsoleSkFeignClient;
import com.mingqijia.gassafety.webserver.request.ConsumerBatchAllocationAreaReq;
import com.mingqijia.gassafety.webserver.request.ConsumerFuncAreaRequest;
import com.mingqijia.gassafety.webserver.request.ConsumerMapGroupRequest;
import com.mingqijia.gassafety.webserver.request.ConsumerMapRequest;
import com.mingqijia.gassafety.webserver.request.console.sk.ConsoleSkAlarmGroupRequest;
import com.mingqijia.gassafety.webserver.request.console.sk.ConsoleSkAlarmMapListRequest;
import com.mingqijia.gassafety.webserver.response.*;
import com.mingqijia.gassafety.webserver.response.baidu.BaiDuDetailResp;
import com.mingqijia.gassafety.webserver.response.sk.*;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.utils.CoordinatesTransitionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.FUNC_AREA_ALLOCAT_CUSTOM;

/**
 * 客户地图
 * @Author: duanhongxiang
 * @Date: 2024/4/26 15:23
 */
@Service
@Slf4j
public class ConsumerLocationServiceImpl extends ServiceImpl<ConsumerLocationMapper, ConsumerLocation> implements ConsumerLocationService {
    @Value("${baidu.maps.key}")
    private String baiDuMapsKey;

    @Resource
    OrganizationService organizationService;
    
    @Resource
    ConsumerLocationMapper consumerLocationMapper;
    
    @Resource
    RedisTemplate redisTemplate;
    
    @Resource
    DtuMapper dtuMapper;
    
    @Resource
    FuncAreaMapper funcAreaMapper;

    @Autowired
    ConsoleSkFeignClient consoleSkFeignClient;
    
    @Resource
    FunctionAreaService functionAreaService;
    
    @Resource
    FieldTemplateMapper fieldTemplateMapper;

    @Resource
    ConsumerMapper consumerMapper;

    @Autowired
    DictionaryService dictionaryService;

    @Resource
    ConsumerService consumerService;

    @Resource
    UserPermissionService userPermissionService;

    @Autowired
    LocationUtil locationUtil;

    @Autowired
    BmapRegionMapper bmapRegionMapper;

    @Autowired
    BusinessNoticeService businessNoticeService;

    private static final String CUST_DISTRICT_REDIS_KEY = "GASSAFETY:REGION:%s";

    private static final String CUST_CITY_NAME_CODE_REDIS_KEY = "GASSAFETY:CITYNAMECODE";
    
    
    
    @Override
    public ConsumerMapGroupResponse queryCustMapGroupList(ConsumerMapGroupRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        //所属组织
        List<String> spIds = organizationService.getSpIds(spId);
        
        double zoom = request.getZoom();
        Map<String,String> zoomMap = dictionaryService.getFuncAreaZoom(spId);
        if( "0".equals(zoomMap.get("city")) && "0".equals(zoomMap.get("district")) && "0".equals(zoomMap.get("street")) ){
            throw new RuntimeException("该企业无需展示聚合数据");
        }
//        zoomMap.put("street","12-15");
//        zoomMap.put("district","10-12");
//        zoomMap.put("city","0-10");
        
        String level = "street";
        for (String key : zoomMap.keySet()) {
            String zoomStr = null==zoomMap.get(key)?"":zoomMap.get(key);
            String[] strArr = zoomStr.split("-");
            if (strArr.length == 2) {
                int minZoom = Integer.parseInt(strArr[0]);
                int maxZoom = Integer.parseInt(strArr[1]);
                if( zoom >= minZoom && zoom < maxZoom ){
                    level = key;
                    break;
                }
            }
        }

        //数据权限
        UserFuncCodePermissionDTO userPermission = userPermissionService.getUserDepartPermission(spIds);

        List<ConsumerLocationGroupItemVO> itemVOList = consumerLocationMapper.selectConsumerGroupList(spIds,level,request.getDeviceStatus(),userPermission.getFuncCodes());
        List<String> cityCodes = new ArrayList<>();
        for (ConsumerLocationGroupItemVO item:itemVOList) {
            if( !cityCodes.contains(item.getCitycode()) ){
                cityCodes.add(item.getCitycode());
            }
        }
        
        //获取行政区信息
        Map<String,AdInfoDTO> allAdInfo = new HashMap<>();
        FieldTemplate fieldTemplate = fieldTemplateMapper.getTypeBySpId(spId);
        if( FUNC_AREA_ALLOCAT_CUSTOM.equals(fieldTemplate.getFuncAreaAllocat()) ){
            allAdInfo = functionAreaService.getFuncAreaMapByCode();
        }else if( cityCodes.size()>0 ){
            for (String cityCode:cityCodes) {
                Map<String,AdInfoDTO> adInfoMap = getCityAdInfo(cityCode);
                allAdInfo.putAll(adInfoMap);
            }
        }
        
        //遍历数据处理
        String key = "";
        List<ConsumerMapGroupItemResponse> list = new ArrayList<>();
        for (ConsumerLocationGroupItemVO itemVO: itemVOList) {
            ConsumerMapGroupItemResponse groupItemResponse = new ConsumerMapGroupItemResponse();
            groupItemResponse.setCount(itemVO.getCnt());

            if( FUNC_AREA_ALLOCAT_CUSTOM.equals(fieldTemplate.getFuncAreaAllocat()) ) {
                if ("city".equals(level)) {
                    key = itemVO.getCitycode();
                    groupItemResponse.setAdCode(itemVO.getCitycode());
                } else if ("district".equals(level)) {
                    key = itemVO.getAdcode();
                    groupItemResponse.setAdCode(itemVO.getAdcode());
                } else {//street
                    key = itemVO.getTowncode();
                    groupItemResponse.setAdCode(itemVO.getTowncode());
                }
            }else{
                if( "city".equals(level) ){
                    key = itemVO.getCitycode();
                    groupItemResponse.setAdCode(itemVO.getCitycode());
                }else if ("district".equals(level)){
                    key = itemVO.getCitycode() + "_" + itemVO.getAdcode();
                    groupItemResponse.setAdCode(itemVO.getAdcode());
                }else {//street
                    key = itemVO.getCitycode() + "_" + itemVO.getAdcode() + "_" + itemVO.getTowncode();
                    groupItemResponse.setAdCode(itemVO.getTowncode());
                }
            }
            if( allAdInfo.containsKey(key) ){
                String center = allAdInfo.get(key).getCenter();
                if( FUNC_AREA_ALLOCAT_CUSTOM.equals(fieldTemplate.getFuncAreaAllocat()) ){
                    if ( (StringUtils.isEmpty(center)  || !center.contains(",")) &&
                            null != itemVO.getLng() && null != itemVO.getLat()) {
                        center = itemVO.getLng() +","+ itemVO.getLat();
                    }
                }else if ( StringUtils.isEmpty(center) && null != itemVO.getLng() && null != itemVO.getLat()) {
                    center = itemVO.getLng() +","+ itemVO.getLat();
                }
                if( StringUtils.isNotEmpty(center) && center.contains(",") ){
                    groupItemResponse.setLngLat(center.split(","));
                    groupItemResponse.setLevel(allAdInfo.get(key).getLevel());
                    groupItemResponse.setAdName(allAdInfo.get(key).getName());
                    list.add(groupItemResponse);
                }
            }
        }

        ConsumerMapGroupResponse consumerMapGroupResponse = new ConsumerMapGroupResponse();
        consumerMapGroupResponse.setLevel(level);
        consumerMapGroupResponse.setList(list);
        return consumerMapGroupResponse;
    }

    @Override
    public ConsumerMapResponse queryBoundaryCustList(ConsumerMapRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        //所属组织
        List<String> spIds = organizationService.getSpIds(spId);
        
        String nELatLng = request.getNorthEastLatLng();
        String sWLatLng = request.getSouthWestLatLng();

        String polygon = null;
        if( StringUtils.isNotEmpty(nELatLng) && StringUtils.isNotEmpty(sWLatLng) ){
            String[] nELatLngArr = nELatLng.split(",");
            if( nELatLngArr.length!=2 ){
                throw new BizException("左上角经纬度不合法");
            }
            String[] sWLatLngArr = sWLatLng.split(",");
            if( sWLatLngArr.length!=2 ){
                throw new BizException("右下角经纬度不合法");
            }
            String boundary = nELatLngArr[0]+" "+nELatLngArr[1]+","+nELatLngArr[0]+" "+sWLatLngArr[1]+","
                    +sWLatLngArr[0]+" "+sWLatLngArr[1]+","+sWLatLngArr[0]+" "+nELatLngArr[1]+","
                    +nELatLngArr[0]+" "+nELatLngArr[1];
            polygon = "POLYGON(("+boundary+"))";
            log.info("nELatLng:{},sWLatLng:{}，polygon:{}",nELatLng,sWLatLng,polygon);
        }
        
        ConsumerMapResponse consumerMapResponse = new ConsumerMapResponse();
        List<ConsumerMapItemResponse> list = new ArrayList<>();

        //数据权限
        UserFuncCodePermissionDTO userPermission = userPermissionService.getUserDepartPermission(spIds);
        List<ConsumerLocationItemVO> locationItemVOS = consumerLocationMapper.selectConsumerLocationList(spIds,polygon,request.getDeviceStatus(),userPermission.getFuncCodes());
        if( StringUtils.isEmpty(request.getDeviceStatus()) ){
            if( ObjectUtil.isEmpty(locationItemVOS) ){
                consumerMapResponse.setList(list);
                return consumerMapResponse;
            }
        }
        
        for (ConsumerLocationItemVO consumerLocationItemVO: locationItemVOS) {
            ConsumerMapItemResponse response = new ConsumerMapItemResponse();
            BeanUtils.copyProperties(consumerLocationItemVO,response);
            response.setId(consumerLocationItemVO.getConsumerId());
            response.setStatusAnybroken(false);
            response.setStatusAnyalert(false);
            response.setStatusAnyoffline(false);
            response.setStatusAnynormal(true);
            if(consumerLocationItemVO.getBrokenNum()>0){
                response.setStatusAnybroken(true);
            }
            if(consumerLocationItemVO.getAlertNum()>0){
                response.setStatusAnyalert(true);
            }
            if(consumerLocationItemVO.getOfflineNum()>0){
                response.setStatusAnyoffline(true);
            }
            if(consumerLocationItemVO.getDeviceNum() > 0 && 
                    consumerLocationItemVO.getOfflineNum().equals(consumerLocationItemVO.getDeviceNum())){
                response.setStatusAnynormal(false);
            }else{
                response.setStatusAnynormal(false);
            }
            list.add(response);
        }
        consumerMapResponse.setList(list);
        return consumerMapResponse;
    }

    @Override
    public Map<String, AdInfoDTO> getCityAdInfo(String adCode){
        String redisKey = String.format(CUST_DISTRICT_REDIS_KEY, adCode);
        Map<String,String> result = redisTemplate.opsForHash().entries(redisKey);
        if( ObjectUtil.isEmpty(result) ){
            result = new HashMap<>();
            JSONObject resultJson = locationUtil.getBaiduRegion(adCode,"3");
            Map<String,String> regionCenterMap = getBaiDuMapRegionCenter(adCode);
            if ("0".equalsIgnoreCase(resultJson.getString("status"))) {
                JSONArray districts = resultJson.getJSONArray("districts");
                if (ObjectUtil.isNotEmpty(districts)){
                    JSONArray jsonArray = new JSONArray();
                    jsonArray.set(0,districts.get(0));
                    this.getSubStrictList(jsonArray,regionCenterMap,result,"","");
                    redisTemplate.opsForHash().putAll(redisKey,result);
                }
            }
        }
        if (MapUtils.isEmpty(result)){
            return new HashMap<>();
        }
        Map<String,AdInfoDTO> resp = new HashMap<>();
        for (Map.Entry<String, String> entry : result.entrySet()) {
            resp.put(entry.getKey(), JSONObject.parseObject(entry.getValue(),AdInfoDTO.class));
        }
        return resp;
    }

    @Override
    public void batchAllocationArea(ConsumerBatchAllocationAreaReq areaReq) {
        List<Integer> consumerId = areaReq.getConsumerId();
        String spId = ApplicationUtils.getWorkingSpId();
        //批量查询客户地址数据
        QueryWrapper<ConsumerLocation> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(ConsumerLocation::getConsumerId, consumerId)
        .eq(ConsumerLocation::getIsDeleted, 0).eq(ConsumerLocation::getSpId, spId);
        List<ConsumerLocation> consumerLocations = consumerLocationMapper.selectList(queryWrapper);
        //批量查询新增客户数据
        QueryWrapper<Consumer> consumerWrappers = new QueryWrapper<>();
        consumerWrappers.lambda().in(Consumer::getId, consumerId)
                .eq(Consumer::getIsDeleted, 0).eq(Consumer::getSpId, spId);
        List<Consumer> consumerList = consumerMapper.selectList(consumerWrappers);
        if (CollectionUtils.isNotEmpty(consumerList)) {
            List<Consumer> consumers = new ArrayList<>();
            for (Consumer consumer : consumerList) {
                consumer.setCitycode(areaReq.getAdCode());
                consumer.setDistrictcode(areaReq.getTownCode());
                consumer.setTowncode(areaReq.getBusinessAreaCode());
                consumers.add(consumer);
            }
            consumerService.updateConsumer(consumers);
        }
        if (CollectionUtils.isNotEmpty(consumerLocations)) {
            List<Integer> consumerIds = new ArrayList<>();
            //修改的集合
            List<ConsumerLocation> updateLocationList = new ArrayList<>();
            for (ConsumerLocation consumerLocation : consumerLocations) {
                consumerIds.add(consumerLocation.getConsumerId());
                consumerLocation.setCity(areaReq.getDistrict());
                consumerLocation.setCitycode(areaReq.getAdCode());
                consumerLocation.setDistrict(areaReq.getTownship());
                consumerLocation.setAdcode(areaReq.getTownCode());
                consumerLocation.setTownship(areaReq.getBusinessArea());
                consumerLocation.setTowncode(areaReq.getBusinessAreaCode());
                updateLocationList.add(consumerLocation);
            }
            //批量修改客户地址
            this.saveOrUpdateBatch(updateLocationList);
            List<Integer> addconsumerIds = new ArrayList<>();
            for (Integer id : consumerId) {
                //当客户id不存在的需要新增客户地址
                if (!consumerIds.contains(id)) {
                    addconsumerIds.add(id);
                }
            }
            if (CollectionUtils.isNotEmpty(addconsumerIds)) {
                //批量查询新增客户数据
                QueryWrapper<Consumer> consumerWrapper = new QueryWrapper<>();
                consumerWrapper.lambda().in(Consumer::getId, addconsumerIds)
                        .eq(Consumer::getIsDeleted, 0).eq(Consumer::getSpId, spId);
                List<Consumer> consumers = consumerMapper.selectList(consumerWrapper);
                //新增的集合
                List<ConsumerLocation> addLocationList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(consumers)) {
                    for (Consumer consumer : consumers) {
                        ConsumerLocation consumerLocation = new ConsumerLocation();
                        consumerLocation.setLat(consumer.getPositionLat());
                        consumerLocation.setLng(consumer.getPositionLon());
                        consumerLocation.setConsumerId(consumer.getId());
                        consumerLocation.setCity(areaReq.getDistrict());
                        consumerLocation.setCitycode(areaReq.getAdCode());
                        consumerLocation.setDistrict(areaReq.getTownship());
                        consumerLocation.setAdcode(areaReq.getTownCode());
                        consumerLocation.setTownship(areaReq.getBusinessArea());
                        consumerLocation.setTowncode(areaReq.getBusinessAreaCode());
                        consumerLocation.setSpId(spId);
                        consumerLocation.setCreatedAt(new Date());
                        consumerLocation.setUpdatedAt(new Date());
                        addLocationList.add(consumerLocation);
                    }
                }
                this.saveOrUpdateBatch(addLocationList);
            }
        } else {
            //新增的集合
            List<ConsumerLocation> addLocationList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(consumerList)) {
                for (Consumer consumer : consumerList) {
                    ConsumerLocation consumerLocation = new ConsumerLocation();
                    consumerLocation.setLat(consumer.getPositionLat());
                    consumerLocation.setLng(consumer.getPositionLon());
                    consumerLocation.setConsumerId(consumer.getId());
                    consumerLocation.setCity(areaReq.getDistrict());
                    consumerLocation.setCitycode(areaReq.getAdCode());
                    consumerLocation.setDistrict(areaReq.getTownship());
                    consumerLocation.setAdcode(areaReq.getTownCode());
                    consumerLocation.setTownship(areaReq.getBusinessArea());
                    consumerLocation.setTowncode(areaReq.getBusinessAreaCode());
                    consumerLocation.setSpId(spId);
                    consumerLocation.setCreatedAt(new Date());
                    consumerLocation.setUpdatedAt(new Date());
                    addLocationList.add(consumerLocation);
                }
            }
            this.saveOrUpdateBatch(addLocationList);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void syncConsumerLocation() {
        int pageIndex = 1;
        int  pageSize = 500;
        long total = 0;
        do{
            Page<ConsumerLocation> pages = PageHelper.startPage(pageIndex, pageSize);
            QueryWrapper<ConsumerLocation> consumerQueryWrapper = new QueryWrapper<>();
            consumerQueryWrapper.lambda().gt(ConsumerLocation::getLat, 0)
                    .gt(ConsumerLocation::getLng, 0);
                    //.eq(ConsumerLocation::getId ,2);
            List<ConsumerLocation> consumerLocations = this.list(consumerQueryWrapper);
            pageIndex++;
            total = pages.getTotal();
            log.info("客户位置表高德转百度{},分页{},{}，{}",pageIndex, pages.getPages(), pages.getPageSize(), pages.getTotal());
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(consumerLocations)) {
                //开始修改坐标
                for (ConsumerLocation consumerLocation : consumerLocations) {
                    if (consumerLocation.getLat() != null && consumerLocation.getLng() != null) {
                        List<BaiDuDetailResp> duDetailResps = CoordinatesTransitionUtil.requestGetAK(consumerLocation.getLng() + "," + consumerLocation.getLat(), baiDuMapsKey);
                        if (CollectionUtils.isNotEmpty(duDetailResps)) {
                            consumerLocation.setLng(duDetailResps.get(0).getX());
                            consumerLocation.setLat(duDetailResps.get(0).getY());
                        }
                    }
                }
                this.saveOrUpdateBatch(consumerLocations);
            }
            consumerLocations.clear();
        }while(total > (pageIndex - 1) * pageSize);
    }

    @Override
    public void syncConsumerLocationCode() {
        int pageIndex = 1;
        int  pageSize = 500;
        long total = 0;
        do{
            Page<ConsumerLocation> pages = PageHelper.startPage(pageIndex, pageSize);
            QueryWrapper<ConsumerLocation> consumerQueryWrapper = new QueryWrapper<>();
            consumerQueryWrapper.lambda().gt(ConsumerLocation::getLat, 0)
                    .gt(ConsumerLocation::getLng, 0);
            //.eq(ConsumerLocation::getId ,2);
            List<ConsumerLocation> consumerLocations = this.list(consumerQueryWrapper);
            pageIndex++;
            total = pages.getTotal();
            log.info("客户位置表高德转百度{},分页{},{}，{}",pageIndex, pages.getPages(), pages.getPageSize(), pages.getTotal());
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(consumerLocations)) {
                //开始修改坐标
                for (ConsumerLocation consumerLocation : consumerLocations) {
                    if (StringUtils.isEmpty(consumerLocation.getCitycode()) || !consumerLocation.getCitycode().contains("D")) {
                        JSONObject resultJson = locationUtil.baiDuGeocoding(consumerLocation.getLat(), consumerLocation.getLng());
                        if ("0".equals(resultJson.getString("status")) &&
                                null != resultJson.getJSONObject("result") &&
                                null != resultJson.getJSONObject("result").getJSONObject("addressComponent")) {
                            JSONObject addressComponent = resultJson.getJSONObject("result").getJSONObject("addressComponent");
                            String province = addressComponent.getString("province");
                            String city = addressComponent.getString("city");
                            if (StringUtils.isEmpty(city)) {
                                city = province;
                            }
                            String citycode = getCityCodeByCityName(province, city, addressComponent.getIntValue("city_level"));
                            String district = addressComponent.getString("district");
                            String adCode = addressComponent.getString("adcode");
                            String towncode = addressComponent.getString("town_code");
                            String township = addressComponent.getString("town");
                            if( StringUtils.isNotEmpty(city) ){
                                consumerLocation.setCity(city);
                            }
                            if( StringUtils.isNotEmpty(citycode) ){
                                consumerLocation.setCitycode(citycode);
                            }
                            if( StringUtils.isNotEmpty(district) ){
                                consumerLocation.setDistrict(district);
                            }
                            if( StringUtils.isNotEmpty(adCode) ){
                                consumerLocation.setAdcode(adCode);
                            }
                            if( StringUtils.isNotEmpty(towncode) ){
                                consumerLocation.setTowncode(towncode);
                            }
                            if( StringUtils.isNotEmpty(township) ){
                                consumerLocation.setTownship(township);
                            }
                        }
                    }

                }
                this.saveOrUpdateBatch(consumerLocations);
            }
            consumerLocations.clear();
        }while(total > (pageIndex - 1) * pageSize);
    }


    private Map<String, String> getSubStrictList(JSONArray districts, Map<String,String> regionCenterMap, Map<String,String> result, String cityCode, String districtCode){
        List<String> levels = new ArrayList<>();
        levels.add("city");
        levels.add("district");
        levels.add("street");
        if( ObjectUtil.isNotEmpty(districts) ){
            for (int i = 0; i < districts.size(); i++) {
                JSONObject jsonObject = districts.getJSONObject(i);
                String level = jsonObject.getString("level");
                String subKey;
                String code = jsonObject.getString("code");
                String name = jsonObject.getString("name");
                AdInfoDTO adInfoDTO = new AdInfoDTO();
                String levelStr = "";
                if( "2".equals(level) ){ //城市
                    subKey = code;
                    adInfoDTO.setCode(code);
                    levelStr = "city";
                    cityCode = code;
                }else if ("3".equals(level)){ //区
                    subKey = cityCode + "_" + code;
                    adInfoDTO.setCode(code);
                    levelStr = "district";
                    districtCode = code;
                }else if ("4".equals(level)){//街道
                    subKey = cityCode + "_" + districtCode + "_"+code;
                    adInfoDTO.setCode(code);
                    levelStr = "street";
                }else{
                    continue;
                }
                adInfoDTO.setName(name);
                adInfoDTO.setLevel(levelStr);
                adInfoDTO.setCenter(regionCenterMap.get(code));
                result.put(subKey,JSONObject.toJSONString(adInfoDTO));
                JSONArray subDistricts = jsonObject.getJSONArray("districts");
                if(ObjectUtil.isNotEmpty(subDistricts)){
                    this.getSubStrictList(subDistricts,regionCenterMap,result,cityCode,districtCode);
                }
            }
        }
        return result;
    }

    /**
     * 获取城市的中心点
     * @param adCode
     * @return
     */
    private Map<String, String> getBaiDuMapRegionCenter(String adCode){
        List<BmapRegion> bmapRegions= bmapRegionMapper.selectRegionsByAdCode(adCode);
        Map<String,String> map = new HashMap<>();
        for (BmapRegion bmapRegion:bmapRegions){
            String center = "";
            if (StringUtils.isNotEmpty(bmapRegion.getCenter()) && bmapRegion.getCenter().split(",").length==2){
                center = bmapRegion.getCenter().split(",")[1]+","+bmapRegion.getCenter().split(",")[0];
            }
            map.put(bmapRegion.getAdCode(),center);
        }
        return map;
    }

    @Override
    public void updateConsumerLocation(Consumer consumer) {
        try {
            log.info("updateConsumerLocation>>更新t_consumer_location客户信息，consumer:{}",JSONObject.toJSONString(consumer));
            FieldTemplate fieldTemplate = fieldTemplateMapper.getTypeBySpId(consumer.getSpId());
            boolean updateLatLngFlag = true;
            if( null!=fieldTemplate && Constants.FUNC_AREA_ALLOCAT_CUSTOM.equals(fieldTemplate.getFuncAreaAllocat()) ){
                updateLatLngFlag = false;
            }
            QueryWrapper<ConsumerLocation> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ConsumerLocation::getConsumerId, consumer.getId());
            queryWrapper.lambda().eq(ConsumerLocation::getIsDeleted, 0);
            List<ConsumerLocation> consumerLocations = consumerLocationMapper.selectList(queryWrapper);
            if (consumerLocations.size() > 0) {
                ConsumerLocation consumerLocation = consumerLocations.get(0);

                LambdaUpdateWrapper<ConsumerLocation> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(ConsumerLocation::getId, consumerLocation.getId());

                double lat = -1;
                double lng = -1;
                if (null != consumer.getPositionLat()) {
                    lat = consumer.getPositionLat();
                }
                if (null != consumer.getPositionLon()) {
                    lng = consumer.getPositionLon();
                }
                if (lat != consumerLocation.getLat() || lng != consumerLocation.getLng()) {

                    updateWrapper.set(ConsumerLocation::getLat,lat);
                    updateWrapper.set(ConsumerLocation::getLng,lng);

                    if( updateLatLngFlag ){
                        Map<String, String> location = transConsumerLatLng(lat, lng);
                        if (null != location) {
                            updateWrapper.set(ConsumerLocation::getCity, location.get("city"));
                            updateWrapper.set(ConsumerLocation::getCitycode, location.get("citycode"));
                            updateWrapper.set(ConsumerLocation::getDistrict, location.get("district"));
                            updateWrapper.set(ConsumerLocation::getAdcode, location.get("adCode"));
                            updateWrapper.set(ConsumerLocation::getTowncode, location.get("towncode"));
                            updateWrapper.set(ConsumerLocation::getTownship, location.get("township"));
                            syncUpdateConsumerAdInfo(consumer,location);
                        }
                    }
                    updateWrapper.set(ConsumerLocation::getIsDeleted,consumer.getIsDeleted());
                    this.update(updateWrapper);
                }
            } else {
                ConsumerLocation consumerLocation = new ConsumerLocation();
                consumerLocation.setConsumerId(consumer.getId());
                if (null == consumer.getPositionLat()) {
                    consumerLocation.setLat((double) -1);
                } else {
                    consumerLocation.setLat(consumer.getPositionLat());
                }
                if (null == consumer.getPositionLon()) {
                    consumerLocation.setLng((double) -1);
                } else {
                    consumerLocation.setLng(consumer.getPositionLon());
                }
                if( updateLatLngFlag ) {
                    Map<String, String> location = transConsumerLatLng(consumer.getPositionLat(), consumer.getPositionLon());
                    if (null != location) {
                        consumerLocation.setCity(location.get("city"));
                        consumerLocation.setCitycode(location.get("citycode"));
                        consumerLocation.setDistrict(location.get("district"));
                        consumerLocation.setAdcode(location.get("adCode"));
                        consumerLocation.setTowncode(location.get("towncode"));
                        consumerLocation.setTownship(location.get("township"));
                        syncUpdateConsumerAdInfo(consumer,location);
                    }
                }
                consumerLocation.setIsDeleted(consumer.getIsDeleted());
                consumerLocation.setSpId(consumer.getSpId());
                consumerLocationMapper.insert(consumerLocation);

            }
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        }
    }

    private void syncUpdateConsumerAdInfo(Consumer consumer,Map<String,String> checkResult){
        LambdaUpdateWrapper<Consumer> consumerUpdateWrapper = new LambdaUpdateWrapper<>();
        consumerUpdateWrapper.eq(Consumer::getSpId, consumer.getSpId())
                .eq(Consumer::getId, consumer.getId())
                .set(Consumer::getCitycode, checkResult.get("citycode"))
                .set(Consumer::getDistrictcode, checkResult.get("adCode"))
                .set(Consumer::getTowncode, checkResult.get("towncode"));
        consumerService.update(consumerUpdateWrapper);
    }

    @Override
    public void updateConsumerLocationCustom(Consumer consumer, ConsumerFuncAreaRequest funcAreaRequest) {
        if (funcAreaRequest == null) {
            return;
        }
        Map<String,String> checkResult = checkFuncAreaParam(consumer.getSpId(),funcAreaRequest);
        
        try {
            log.info("updateConsumerLocationCustom>>更新t_consumer_location客户信息，consumer:{}",JSONObject.toJSONString(consumer));
            QueryWrapper<ConsumerLocation> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ConsumerLocation::getConsumerId, consumer.getId());
            queryWrapper.lambda().eq(ConsumerLocation::getIsDeleted, 0);
            List<ConsumerLocation> consumerLocations = consumerLocationMapper.selectList(queryWrapper);
            
            if ( null!=consumerLocations && !consumerLocations.isEmpty() ) {
                ConsumerLocation consumerLocation = consumerLocations.get(0);
                LambdaUpdateWrapper<ConsumerLocation> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(ConsumerLocation::getId, consumerLocation.getId());
                double lat = -1;
                double lng = -1;
                if (null != consumer.getPositionLat()) {
                    lat = consumer.getPositionLat();
                }
                if (null != consumer.getPositionLon()) {
                    lng = consumer.getPositionLon();
                }
                if (lat != consumerLocation.getLat() || lng != consumerLocation.getLng()) {
                    updateWrapper.set(ConsumerLocation::getLat,lat);
                    updateWrapper.set(ConsumerLocation::getLng,lng);
                }
                updateWrapper.set(ConsumerLocation::getCity,checkResult.get("city"));
                updateWrapper.set(ConsumerLocation::getCitycode,checkResult.get("citycode"));
                updateWrapper.set(ConsumerLocation::getDistrict,checkResult.get("district"));
                updateWrapper.set(ConsumerLocation::getAdcode,checkResult.get("adCode"));
                updateWrapper.set(ConsumerLocation::getTowncode,checkResult.get("towncode"));
                updateWrapper.set(ConsumerLocation::getTownship,checkResult.get("township"));
                updateWrapper.set(ConsumerLocation::getIsDeleted,consumer.getIsDeleted());
                this.update(updateWrapper);
                syncUpdateConsumerAdInfo(consumer,checkResult);
            } else {
                ConsumerLocation consumerLocation = new ConsumerLocation();
                consumerLocation.setConsumerId(consumer.getId());
                if (null == consumer.getPositionLat()) {
                    consumerLocation.setLat((double) -1);
                } else {
                    consumerLocation.setLat(consumer.getPositionLat());
                }
                if (null == consumer.getPositionLon()) {
                    consumerLocation.setLng((double) -1);
                } else {
                    consumerLocation.setLng(consumer.getPositionLon());
                }
                consumerLocation.setCity(checkResult.get("city"));
                consumerLocation.setCitycode(checkResult.get("citycode"));
                consumerLocation.setDistrict(checkResult.get("district"));
                consumerLocation.setAdcode(checkResult.get("adCode"));
                consumerLocation.setTowncode(checkResult.get("towncode"));
                consumerLocation.setTownship(checkResult.get("township"));
                consumerLocation.setIsDeleted(consumer.getIsDeleted());
                consumerLocation.setSpId(consumer.getSpId());
                consumerLocationMapper.insert(consumerLocation);
                syncUpdateConsumerAdInfo(consumer,checkResult);
            }
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        } 
    }

    /**
     * 校验功能区域入参
     * @param spId
     * @param funcAreaRequest
     * @return
     */
    private Map<String,String> checkFuncAreaParam(String spId,ConsumerFuncAreaRequest funcAreaRequest){
        String cityCode = null;
        String city = null;
        String district = null;
        String adCode = null;
        String towncode = null;
        String township = null;
        FuncArea funcArea;
        
        if( StringUtils.isEmpty(funcAreaRequest.getDistrictCode()) && StringUtils.isEmpty(funcAreaRequest.getStreetCode())
         && StringUtils.isEmpty(funcAreaRequest.getBusinessAreaCode()) ){
            funcAreaRequest = null;
        }
        
        if( !ObjectUtil.isEmpty(funcAreaRequest) ) {
            if (StringUtils.isEmpty(funcAreaRequest.getDistrictCode())) {
                throw new BizException("区必选");
            } else {
                funcArea = getFunctionAreaByParam(spId, 1, funcAreaRequest.getDistrictCode());
                if (ObjectUtils.isEmpty(funcArea)) {
                    throw new BizException("根据区code找不到对应的区数据");
                }
                cityCode = funcArea.getFuncCode();
                city = funcArea.getFuncName();
            }
            if (!StringUtils.isEmpty(funcAreaRequest.getStreetCode())) {
                funcArea = getFunctionAreaByParam(spId, 2, funcAreaRequest.getStreetCode());
                if (ObjectUtils.isEmpty(funcArea)) {
                    throw new BizException("根据街道code找不到对应的街道数据");
                }
                adCode = funcArea.getFuncCode();
                district = funcArea.getFuncName();
            }

            if (StringUtils.isNotEmpty(funcAreaRequest.getBusinessAreaCode())) {
                funcArea = getFunctionAreaByParam(spId, 3, funcAreaRequest.getBusinessAreaCode());
                if (ObjectUtils.isEmpty(funcArea)) {
                    throw new BizException("根据商圈code找不到对应的商圈数据");
                }
                towncode = funcArea.getFuncCode();
                township = funcArea.getFuncName();
            }
        }
        Map<String,String> result = new HashMap<>();
        result.put("citycode",cityCode);
        result.put("city",city);
        result.put("adCode",adCode);
        result.put("district",district);
        result.put("towncode",towncode);
        result.put("township",township);
        return result;
    }

    /**
     * 获取功能区域代码
     * @param spId
     * @param level
     * @param funcCode
     * @return
     */
    private FuncArea getFunctionAreaByParam(String spId,Integer level,String funcCode){
        LambdaQueryWrapper<FuncArea> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FuncArea::getSpId, spId);
        queryWrapper.eq(FuncArea::getIsDeleted, false);
        queryWrapper.eq(FuncArea::getFuncCode, funcCode);
        queryWrapper.eq(FuncArea::getLevel, level);
        return funcAreaMapper.selectOne(queryWrapper);
    }
    

    @Override
    public void updateConsumerLocationDeviceNum(String spId, Integer consumerId) {
        try {
            log.info("updateConsumerLocationDeviceNum>>更新t_consumer_location表设备各个状态信息，spId:{},consumerId:{}",
                    spId, consumerId);
            if (null == consumerId || consumerId.equals(0)) {
                return;
            }
            ConsumerLocationStatItemVO consumerLocationStatItemVO = consumerLocationMapper.selectConsumerLocationStat(spId, consumerId);
            log.info("consumerLocationStatItemVO:{}", consumerLocationStatItemVO);
            if (ObjectUtil.isEmpty(consumerLocationStatItemVO)) {
                consumerLocationStatItemVO = new ConsumerLocationStatItemVO();
                consumerLocationStatItemVO.setConsumerId(consumerId);
                consumerLocationStatItemVO.setDeviceNum(0);
                consumerLocationStatItemVO.setAlertNum(0);
                consumerLocationStatItemVO.setBrokenNum(0);
                consumerLocationStatItemVO.setOfflineNum(0);
            }
            log.info("更新t_consumer_location表设备各个状态信息，spId:{},consumerId:{},consumerLocationStatItemVO:{}",
                    spId, consumerId, JSONObject.toJSONString(consumerLocationStatItemVO));
            consumerLocationMapper.updateConsumerDeviceNum(spId, consumerId, consumerLocationStatItemVO);
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        }
    }

    @Override
    public void deleteConsumerLocation(String spId, Integer consumerId) {
        try {
            log.info("deleteConsumerLocation>>删除t_consumer_location表信息，spId:{},consumerId:{}", spId, consumerId);
            QueryWrapper<ConsumerLocation> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ConsumerLocation::getConsumerId, consumerId)
                    .eq(ConsumerLocation::getSpId, spId);
            ConsumerLocation consumerLocation = new ConsumerLocation();
            consumerLocation.setIsDeleted(true);
            consumerLocationMapper.update(consumerLocation, queryWrapper);
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        }
    }

    @Override
    public void updateConsumerLocationDeviceNumByDeviceId(String spId, String deviceId) {
        try {
            log.info("updateConsumerLocationDeviceNumByDeviceId>>更新t_consumer_location表设备各个状态信息，spId:{},deviceId:{}",
                    spId, deviceId);
            Dtu dtu = dtuMapper.selectById(deviceId);
            if (ObjectUtil.isEmpty(dtu) || null == dtu.getConsumerId()) {
                return;
            }
            updateConsumerLocationDeviceNum(spId, dtu.getConsumerId());
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        }
    }

    @Override
    public void updateConsumerLocationDeviceNumByDtu(Dtu dtu) {
        try {
            log.info("updateConsumerLocationDeviceNumByDtu>>更新t_consumer_location表设备各个状态信息，",
                    JSONObject.toJSONString(dtu));
            if (ObjectUtil.isEmpty(dtu) || null == dtu.getConsumerId()) {
                return;
            }
            updateConsumerLocationDeviceNum(dtu.getSpId(), dtu.getConsumerId());
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        }
    }

    @Override
    public void updateConsumerLocationDeviceNumByImei(String spId, String imei) {
        try {
            log.info("updateConsumerLocationDeviceNumByImei>>更新t_consumer_location表设备各个状态信息，spId:{},deviceId:{}",
                    spId, imei);
            Dtu dtu = dtuMapper.selectByImei(imei, "");
            if (ObjectUtil.isEmpty(dtu) || null == dtu.getConsumerId()) {
                return;
            }
            updateConsumerLocationDeviceNum(spId, dtu.getConsumerId());
        }catch (Exception e){
            log.error("同步更新t_consumer_location表失败",e);
        }
    }

    /**
     * 转换客户的经纬度
     * @param lat
     * @param lng
     * @return
     */
    public Map<String,String> transConsumerLatLng(Double lat, Double lng){
        Map<String,String> result = new HashMap<>();
        result.put("city",null);
        result.put("citycode",null);
        result.put("district",null);
        result.put("adCode",null);
        result.put("towncode",null);
        result.put("township",null);
        if( null==lat || null == lng || lat<=0 || lng<=0){
            return result;
        }
        JSONObject resultJson = locationUtil.baiDuGeocoding(lat,lng);
        if ("0".equals(resultJson.getString("status")) &&
                null!=resultJson.getJSONObject("result") &&
                null!=resultJson.getJSONObject("result").getJSONObject("addressComponent")) {
            JSONObject addressComponent = resultJson.getJSONObject("result").getJSONObject("addressComponent");
            String province = addressComponent.getString("province");
            String city = addressComponent.getString("city");
            if( StringUtils.isEmpty(city) ){
                city = province;
            }
            String citycode = getCityCodeByCityName(province,city,addressComponent.getIntValue("city_level"));
            String district = addressComponent.getString("district");
            String adCode = addressComponent.getString("adcode");
            String towncode = addressComponent.getString("town_code");
            String township = addressComponent.getString("town");
            result.put("city",city);
            result.put("citycode",citycode);
            result.put("district",district);
            result.put("adCode",adCode);
            result.put("towncode",towncode);
            result.put("township",township);
            return result;
        }
        return result;
    }

    /**
     *
     * @param provinceName
     * @param cityName
     * @param cityLevel
     * @return
     */
    @Override
    public String getCityCodeByCityName(String provinceName,String cityName, int cityLevel){
        try {
            String hKey = provinceName + "_" + cityName;
            Object result = redisTemplate.opsForHash().get(CUST_CITY_NAME_CODE_REDIS_KEY, hKey);
            if (null == result || ObjectUtil.isEmpty(result)) {
                JSONObject resultJson = locationUtil.getBaiduRegion(provinceName,"1");
                if ("0".equalsIgnoreCase(resultJson.getString("status"))) {
                    JSONArray districts = resultJson.getJSONArray("districts");
                    String cityCode = "";
                    if (ObjectUtil.isNotEmpty(districts)) {
                        for (int i = 0; i < districts.size(); i++) {
                            if (1 == districts.getJSONObject(i).getInteger("level")) {
                                JSONArray subDistricts = districts.getJSONObject(i).getJSONArray("districts");
                                for (int j = 0; j < subDistricts.size(); j++) {
                                    if (cityLevel == subDistricts.getJSONObject(j).getInteger("level") &&
                                            cityName.equals(subDistricts.getJSONObject(j).getString("name"))) {
                                        cityCode = subDistricts.getJSONObject(j).getString("code");
                                        break;
                                    }
                                }
                                if (StringUtils.isNotEmpty(cityCode)) {
                                    break;
                                }
                            } else if (cityLevel == districts.getJSONObject(i).getInteger("level") &&
                                    cityName.equals(districts.getJSONObject(i).getString("name"))) {
                                cityCode = districts.getJSONObject(i).getString("code");
                                break;
                            }
                        }
                        if (StringUtils.isNotEmpty(cityCode)) {
                            redisTemplate.opsForHash().put(CUST_CITY_NAME_CODE_REDIS_KEY, hKey, cityCode);
                        }
                        return cityCode;
                    }
                }
                return "";
            } else {
                return result.toString();
            }
        }catch (Exception e){
            log.error("getCityCodeByCityName error",e);
        }
        return "";
    }

    @Override
    public List<Double> selectAlertPosition() {
        String spId = ApplicationUtils.getWorkingSpId();
        //所属组织
        List<String> spIds = organizationService.getSpIds(spId);
        //数据权限
        UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(spIds);

        boolean servicePkgModeSwitch = businessNoticeService.switchValueByCode(
                BusinessNoticeParam.DIFFERENT_SERVICE_PACKAGE_MODE.getCode(),
                spId);
        String servicePkgMode = "";
        if (servicePkgModeSwitch){
            servicePkgMode = ServicePkgEnum.AUTO_LOCATE_IN.getCode();
        }

        ConsumerLocationItemVO locationItemVo = consumerLocationMapper.selectAlertPosition(spIds,
                "alert", userFuncCodePermission.getFuncCodes(), servicePkgMode);
        if (locationItemVo != null && locationItemVo.getPositionLon() != null && locationItemVo.getPositionLat() != null) {
            return Arrays.asList(locationItemVo.getPositionLon(), locationItemVo.getPositionLat());
        }

        locationItemVo = consumerLocationMapper.selectAlertPosition(spIds,
                "broken", userFuncCodePermission.getFuncCodes(),servicePkgMode);
        if (locationItemVo != null && locationItemVo.getPositionLon() != null && locationItemVo.getPositionLat() != null) {
            return Arrays.asList(locationItemVo.getPositionLon(), locationItemVo.getPositionLat());
        }
        return null;
    }

    @Override
    public ConsumerMapGroupResponse queryCustMapGroupListWithKitchen(ConsumerMapGroupRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        Map<String,ConsumerMapGroupItemResponse> allDataMap = new HashMap<>();
        ConsumerMapGroupResponse alarmResponse = new ConsumerMapGroupResponse();
        
        try {
            alarmResponse = this.queryCustMapGroupList(request);
            if (ObjectUtil.isNotEmpty(alarmResponse) && ObjectUtil.isNotEmpty(alarmResponse.getList())) {
                for (ConsumerMapGroupItemResponse groupItem : alarmResponse.getList()) {
                    allDataMap.put(groupItem.getAdCode(), groupItem);
                }
            }
        }catch (Exception e){
            log.error("queryCustMapGroupListWithKitchen->获取报警器数据异常",e);
        }
        
        try {
            int zoom = (int) (Math.ceil(request.getZoom()));
            log.info("SOS地图电子围栏请求参数:zoom:{},spId:{}", zoom, spId);
            String newDeviceStatus = "";
            Map<String,String> deviceStatusMap = new HashMap<>();
            deviceStatusMap.put("normal","0");
            deviceStatusMap.put("alert","1");
            deviceStatusMap.put("broken","2");
            deviceStatusMap.put("offline","3");
            if( deviceStatusMap.containsKey(request.getDeviceStatus()) ){
                newDeviceStatus = deviceStatusMap.get(request.getDeviceStatus());
            }
            ConsoleSkAlarmGroupRequest kitchenRequest = new ConsoleSkAlarmGroupRequest();
            kitchenRequest.setZoom(zoom);
            kitchenRequest.setDeviceStatus(newDeviceStatus);
            kitchenRequest.setSpId(spId);
            CommonResponse<ConsoleSkAlarmMapGroupResponse> kitchenResponse = consoleSkFeignClient.alarmSOSMapGroup(kitchenRequest);
            if (ObjectUtil.isNotEmpty(kitchenResponse) && ObjectUtil.isNotEmpty(kitchenResponse.getData()) &&
                    ObjectUtil.isNotEmpty(kitchenResponse.getData().getList())) {
                for (ConsoleSkAlarmMapGroupItemResponse groupItem : kitchenResponse.getData().getList()) {
                    ConsumerMapGroupItemResponse newGroupItem = new ConsumerMapGroupItemResponse();
                    BeanUtils.copyProperties(groupItem, newGroupItem);
                    if (allDataMap.containsKey(newGroupItem.getAdCode())) {
                        newGroupItem.setCount(allDataMap.get(groupItem.getAdCode()).getCount() + newGroupItem.getCount());
                        allDataMap.put(groupItem.getAdCode(), newGroupItem);
                    }else{
                        allDataMap.put(groupItem.getAdCode(), newGroupItem);
                    }
                }
            }
        }catch (Exception e){
            log.error("queryCustMapGroupListWithKitchen->获取智慧厨房数据异常",e);
        }
        alarmResponse.setList(allDataMap.values().stream().collect(Collectors.toList()));
        return alarmResponse;
    }

    @Override
    public ConsumerMapWitchKitchenResponse queryBoundaryCustListWithKitchen(ConsumerMapRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        List<ConsumerMapItemWithKitchenResponse> allList = new ArrayList<>();
        ConsumerMapWitchKitchenResponse allResponse = new ConsumerMapWitchKitchenResponse();
        try {
            ConsumerMapResponse alarmResponse = this.queryBoundaryCustList(request);
            BeanUtils.copyProperties(alarmResponse,allResponse);
            if (ObjectUtil.isNotEmpty(allResponse) && ObjectUtil.isNotEmpty(allResponse.getList())) {
                allList = allResponse.getList();
            }
        }catch (Exception e){
            log.error("queryBoundaryCustListWithKitchen->获取报警器数据异常",e);
        }
        
        try {
            ConsoleSkAlarmMapListRequest alarmMapListRequest = new ConsoleSkAlarmMapListRequest();
            alarmMapListRequest.setNorthEastLatLng(request.getNorthEastLatLng());
            alarmMapListRequest.setSouthWestLatLng(request.getSouthWestLatLng());
            alarmMapListRequest.setSpId(spId);
            Map<String,String> deviceStatusMap = new HashMap<>();
            deviceStatusMap.put("normal","0");
            deviceStatusMap.put("alert","1");
            deviceStatusMap.put("broken","2");
            deviceStatusMap.put("offline","3");
            if( deviceStatusMap.containsKey(request.getDeviceStatus()) ){
                alarmMapListRequest.setDeviceStatus(deviceStatusMap.get(request.getDeviceStatus()));
            }
            log.info("SOS地图电子围栏请求参数:{}", JSONUtil.toJsonStr(alarmMapListRequest));
            CommonResponse<ConsoleSkAlarmMapListResponse> kitchenResponse = consoleSkFeignClient.alarmSOSMapList(alarmMapListRequest);
            if (ObjectUtil.isNotEmpty(kitchenResponse) && ObjectUtil.isNotEmpty(kitchenResponse.getData())
                    && ObjectUtil.isNotEmpty(kitchenResponse.getData().getList())) {
                for (ConsoleSkAlarmMapItemResponse item : kitchenResponse.getData().getList()) {
                    ConsumerMapItemWithKitchenResponse newItem = new ConsumerMapItemWithKitchenResponse();
                    BeanUtils.copyProperties(item, newItem);
                    newItem.setIsFromKitchen(true);
                    if( StringUtils.isNotEmpty(item.getLon()) && StringUtils.isNotEmpty(item.getLat())){
                        newItem.setPositionLon(Double.valueOf(item.getLon()));
                        newItem.setPositionLat(Double.valueOf(item.getLat()));
                    }
                    allList.add(newItem);
                }
            }
        }catch (Exception e){
            log.error("queryBoundaryCustListWithKitchen->获取智慧厨房数据异常",e);
        }

        allResponse.setList(allList);
        return allResponse;
    }

    @Override
    public List<Double> selectAlertPositionWithKitchen() {
        String spId = ApplicationUtils.getWorkingSpId();
        //所属组织
        List<String> spIds = organizationService.getSpIds(spId);

        //数据权限
        UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(spIds);

        boolean servicePkgModeSwitch = businessNoticeService.switchValueByCode(
                BusinessNoticeParam.DIFFERENT_SERVICE_PACKAGE_MODE.getCode(),
                spId);
        String servicePkgMode = "";
        if (servicePkgModeSwitch){
            servicePkgMode = ServicePkgEnum.AUTO_LOCATE_IN.getCode();
        }

        ConsumerLocationItemVO locationItemVo = consumerLocationMapper.selectAlertPosition(spIds,
                "alert", userFuncCodePermission.getFuncCodes(),servicePkgMode);
        if (locationItemVo == null || locationItemVo.getPositionLon() == null || locationItemVo.getPositionLat() == null) {
            locationItemVo = consumerLocationMapper.selectAlertPosition(spIds,
                    "broken", userFuncCodePermission.getFuncCodes(),servicePkgMode);
            if (locationItemVo == null || locationItemVo.getPositionLon() == null || locationItemVo.getPositionLat() == null) {
                locationItemVo = null;
            }
        }
        
        log.info("alarmSOSFaultList请求参数:{}", spId);
        CommonResponse<ConsoleSkAlarmFaultListResponse> kitchenResponse = consoleSkFeignClient.alarmSOSFaultList(spId);
        log.info("alarmSOSFaultList响应结果:{}", JSONObject.toJSONString(kitchenResponse));
        ConsoleSkAlarmFaultItemResponse kitchenItemVo = null;
        if( ObjectUtil.isNotEmpty(kitchenResponse) && ObjectUtil.isNotEmpty(kitchenResponse.getData()) && 
                ObjectUtil.isNotEmpty(kitchenResponse.getData().getList())){
            for (ConsoleSkAlarmFaultItemResponse faultItem : kitchenResponse.getData().getList()){
                try {
                    if (null != faultItem && StringUtils.isNotEmpty(faultItem.getLat()) && StringUtils.isNotEmpty(faultItem.getLon())) {
                        kitchenItemVo = faultItem;
                        break;
                    }
                }catch (Exception e){
                    log.error("经纬度string转double失败",e);
                }
            }
        }
        if( locationItemVo != null && kitchenItemVo !=null ){
            long updatedAt = locationItemVo.getUpdatedAt().getTime();
            long alarmTime = DateUtil.parse(kitchenItemVo.getAlarmTime(),"yyyy-MM-dd HH:mm:ss").getTime();
            if( updatedAt >= alarmTime ){
                return Arrays.asList(locationItemVo.getPositionLon(), locationItemVo.getPositionLat());
            }else{
                return Arrays.asList(Double.valueOf(kitchenItemVo.getLon()), Double.valueOf(kitchenItemVo.getLat()));
            }
        }else if(  locationItemVo != null ){
            return Arrays.asList(locationItemVo.getPositionLon(), locationItemVo.getPositionLat());
        }else if( kitchenItemVo !=null ){
            return Arrays.asList(Double.valueOf(kitchenItemVo.getLon()), Double.valueOf(kitchenItemVo.getLat()));
        }
        return null;
    }

    @Override
    public Map<Integer,ConsumerFuncAreaResponse> getConsumerFuncArea(List<Integer> consumerIds,String spId, Integer funcAreaAllocat) {
        LambdaQueryWrapper<ConsumerLocation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ConsumerLocation::getSpId,spId);
        queryWrapper.eq(ConsumerLocation::getIsDeleted,false);
        queryWrapper.in(ConsumerLocation::getConsumerId,consumerIds);
        List<ConsumerLocation> consumerLocations = this.baseMapper.selectList(queryWrapper);
        if(consumerLocations.size()==0){
            return null;
        }
        Map<Integer, ConsumerFuncAreaResponse> result = new HashMap<>();
        for (ConsumerLocation consumerLocation : consumerLocations) {
            ConsumerFuncAreaResponse consumerFuncAreaResponse = new ConsumerFuncAreaResponse();
            consumerFuncAreaResponse.setDistrictCode(consumerLocation.getCitycode());
            consumerFuncAreaResponse.setDistrictName(consumerLocation.getCity());
            consumerFuncAreaResponse.setStreetCode(consumerLocation.getAdcode());
            consumerFuncAreaResponse.setStreetName(consumerLocation.getDistrict());
            consumerFuncAreaResponse.setBusinessAreaCode(consumerLocation.getTowncode());
            consumerFuncAreaResponse.setBusinessAreaName(consumerLocation.getTownship());
            result.put(consumerLocation.getConsumerId(), consumerFuncAreaResponse);
        }
        return result;
    }
}
